package com.sunlands.qdcy.tongzhuo.service;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.sunlands.qdcy.tongzhuo.constant.CommonResultMessage;
import com.sunlands.qdcy.tongzhuo.constant.MsgType;
import com.sunlands.qdcy.tongzhuo.constant.TabType;
import com.sunlands.qdcy.tongzhuo.feign.MessageService;
import com.sunlands.qdcy.tongzhuo.feign.MessageVO;
import com.sunlands.qdcy.tongzhuo.feign.SocketClient;
import com.sunlands.qdcy.tongzhuo.feign.vo.UserInfoDTO;
import com.sunlands.qdcy.tongzhuo.vo.BusinessResult;
import com.sunlands.qdcy.tongzhuo.vo.GroupSimpleVO;
import com.sunlands.qdcy.tongzhuo.vo.UserFriendVO;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections.CollectionUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;

import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.stream.Collectors;

/**
 * Created with meng.
 * User: meng5
 * Date: 2019-06-26
 * Description:
 */
@Slf4j
@Service
public class DiaryMessageService extends BaseService {
    @Autowired
    private MessageService messageService;
    @Autowired
    private SocketClient socketClient;

    private static final String EXECUTOR = "msgExecutor";

    /**
     * 创建日记，发送通知给道友和所在的群
     *
     * @param fromUserId
     * @param diaryId
     */
    @Async(EXECUTOR)
    public void diaryPublishNotice(Long fromUserId, Long diaryId) {
        diaryNoticeToFriends(fromUserId, diaryId);
//        diaryNoticeToGroups(fromUserId, diaryId);
    }


    /**
     * 发布日记，通知道友
     *
     * @param fromUserId
     * @param diaryId
     */
    private void diaryNoticeToFriends(Long fromUserId, Long diaryId) {
        if (fromUserId == null || fromUserId == 0) {
            log.error("fromUserId不能为空！");
            return;
        }
        try {

            List<UserFriendVO> friendVOList = userFriendsList(fromUserId);
            if (CollectionUtils.isEmpty(friendVOList)) {
                log.info("房主{}没有道友！", fromUserId);
                return;
            }

            Set<Long> friendIds = friendVOList.stream().map(o -> o.getFriendsUserId()).collect(Collectors.toSet());

            UserInfoDTO hostUser = this.getUserById(fromUserId);
            if (hostUser == null) {
                log.error("未查询到用户信息！hostUserId={}", fromUserId);
                return;
            }

            String msg = hostUser.getName() + "发布了学习日记";

            MsgType msgType = MsgType.person_text;

            Map<String, Object> extraMap = TabType.getTabTypeMap(TabType.person_diary);

            MessageVO param = MessageVO.builder()
                    .businessId(String.valueOf(fromUserId))
                    .content(msg)
                    .isGroupSend(false)
                    .userIds(friendIds)
                    .type(msgType.getCode())
                    .extras(extraMap)
                    .excludeUserIds(Arrays.asList(fromUserId))
                    .build();
            //这里还可以处理黑名单

            BusinessResult result = sendMsg(param);
            log.info("发送消息-完毕：fromUserId={}, diaryId={}, result={}", fromUserId, diaryId, result);
        } catch (Exception e) {
            log.error("发送消息异常：发布日记，通知道友-fromUserId={},diaryId={}", fromUserId, diaryId, e);
        }

    }


    /**
     * 发布日记，通知群
     *
     * @param fromUserId
     * @param diaryId
     */
    private void diaryNoticeToGroups(Long fromUserId, Long diaryId) {
        if (fromUserId == null || fromUserId == 0) {
            log.error("fromUserId不能为空！");
            return;
        }
        try {
            List<GroupSimpleVO> groups = this.getGroupList(fromUserId);
            if (CollectionUtils.isEmpty(groups)) {
                log.info("未查询到该用户添加的群！hostUserId={}", fromUserId);
                return;
            }

            UserInfoDTO hostUser = this.getUserById(fromUserId);
            if (hostUser == null) {
                log.error("未查询到用户信息！hostUserId={}", fromUserId);
                return;
            }

            String msg = hostUser.getName() + "发布了学习日记";

            MsgType msgType = MsgType.group_text;

            Map<String, Object> extraMap = TabType.getTabTypeMap(TabType.group_diary);

            groups.stream().forEach(group -> {

                MessageVO param = MessageVO.builder()
                        .businessId(group.getGroupId())
                        .content(msg)
                        .isGroupSend(true)
                        .type(msgType.getCode())
                        .extras(extraMap)
                        .build();

                BusinessResult result = sendMsg(param);
                log.info("发送消息-完毕：fromUserId={}, diaryId={}, result={}", fromUserId, diaryId, result);

            });

        } catch (Exception e) {
            log.error("发送消息异常：发布日记，通知群-fromUserId={},diaryId={}", fromUserId, diaryId, e);
        }
    }

    /**
     * 点赞了日记
     *
     * @param fromUserId
     * @param toUserId
     */
    @Async(EXECUTOR)
    public void interactZanDiary(Long fromUserId, Long toUserId) {
        this.interactNotice(fromUserId, toUserId, TabType.zan, MsgObjectTip.DIARY);
    }

    /**
     * 点赞了评论
     *
     * @param fromUserId
     * @param toUserId
     */
    @Async(EXECUTOR)
    public void interactZanComment(Long fromUserId, Long toUserId) {
        this.interactNotice(fromUserId, toUserId, TabType.zan, MsgObjectTip.COMMENT);
    }

    /**
     * 转发了日记
     *
     * @param fromUserId
     * @param toUserId
     */
    @Async(EXECUTOR)
    public void interactForwardDiary(Long fromUserId, Long toUserId) {
        this.interactNotice(fromUserId, toUserId, TabType.forward, MsgObjectTip.DIARY);
    }

    /**
     * 转发了评论
     *
     * @param fromUserId
     * @param toUserId
     */
    @Async(EXECUTOR)
    public void interactForwardComment(Long fromUserId, Long toUserId) {
        this.interactNotice(fromUserId, toUserId, TabType.forward, MsgObjectTip.COMMENT);
    }

    /**
     * 回复了日记
     *
     * @param fromUserId
     * @param toUserId
     */
    @Async(EXECUTOR)
    public void interactReplyDiary(Long fromUserId, Long toUserId) {
        this.interactNotice(fromUserId, toUserId, TabType.reply, MsgObjectTip.DIARY);
    }

    /**
     * 回复了评论
     *
     * @param fromUserId
     * @param toUserId
     */
    @Async(EXECUTOR)
    public void interactReplyComment(Long fromUserId, Long toUserId) {
        this.interactNotice(fromUserId, toUserId, TabType.reply, MsgObjectTip.COMMENT);
    }


    /**
     * 互动通知，内部通用方法
     *
     * @param fromUserId
     * @param toUserId
     * @param tabType
     * @param objectTip
     */

    private void interactNotice(Long fromUserId, Long toUserId, TabType tabType, MsgObjectTip objectTip) {
        try {
            UserInfoDTO hostUser = this.getUserById(fromUserId);
            if (hostUser == null) {
                log.error("未查询到用户信息！hostUserId={}", fromUserId);
                return;
            }

            String operate = "";
            switch (tabType) {
                case forward:
                    operate = "转发了";
                    break;
                case zan:
                    operate = "点赞了";
                    break;
                case reply:
                    operate = "回复了";
                    break;
                default: {
                    throw new IllegalArgumentException("非法操作, tabType=" + tabType.getCode());
                }
            }
            String tip = "你的" + objectTip.getTip();
            String msg = hostUser.getName() + operate + tip;

            Map<String, Object> extraMap = TabType.getTabTypeMap(tabType);

            MessageVO param = MessageVO.builder()
                    .businessId(String.valueOf(fromUserId))
                    .content(msg)
                    .userIds(Arrays.asList(toUserId))
                    .isGroupSend(false)
                    .type(MsgType.interact_notice.getCode())
                    .extras(extraMap)
                    .build();

            BusinessResult result = sendMsg(param);
        } catch (Exception e) {
            log.error("发送消息异常：TabType={}, objectTip={}, fromUserId={}, toUserId={}", tabType, objectTip, fromUserId, toUserId);
        }
    }


    private BusinessResult sendMsg(MessageVO param) {
        BusinessResult resultVO = null;
        long t1 = System.currentTimeMillis();
        try {
            resultVO = messageService.sendMessage(param);
            long t2 = System.currentTimeMillis();
            log.info("发送消息-cost:{}ms，param={}，resultVO={}", t2 - t1, JSONObject.toJSONString(param), JSON.toJSONString(resultVO));
            if (resultVO == null || resultVO.getCode() == null || resultVO.getCode().longValue() != CommonResultMessage.SUCCESS.code) {
                log.info("发送消息-失败，cost:{}ms，param={}，resultVO={}", t2 - t1, JSONObject.toJSONString(param), JSON.toJSONString(resultVO));
            }
        } catch (Exception e) {
            log.info("发送消息-异常，param={}，resultVO={}", JSONObject.toJSONString(param), JSON.toJSONString(resultVO), e);
            return BusinessResult.createInstance(CommonResultMessage.DIARY_FAIL);
        }
        return resultVO;
    }


    public enum MsgObjectTip {
        /**
         * 提醒类别
         */
        DIARY("日记"),
        COMMENT("评论");

        private String tip;

        MsgObjectTip(String tip) {
            this.tip = tip;
        }

        public String getTip() {
            return tip;
        }

        public void setTip(String tip) {
            this.tip = tip;
        }
    }

}